using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ShootThemUp.Sources.GameElements.Animations
{
    /// <summary>
    /// This class represents a temporal animation, a special effect like explosion, teleportation effect ...
    /// </summary>
    public class Animation : Sprite
    {
        #region Fields

        /// <summary>
        /// The number of frames used to realise the animation.
        /// </summary>
        private int nbFrames;
        /// <summary>
        /// The width of a frame, used to know the position of the next frame.
        /// </summary>
        private int frameWidth;
        /// <summary>
        /// The duration of a frame.
        /// </summary>
        private float frameDuration;
        /// <summary>
        /// The index of the current frame used.
        /// </summary>
        private float index;
        /// <summary>
        /// The default position of the texture in the spritesheet.
        /// </summary>
        private Vector2 initialSpriteSheetPosition;
        
        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="Animation"/> class.
        /// </summary>
        /// <param name="position">The position of the animation.</param>
        /// <param name="sourceRectangle">The source rectangle, ie the part to display in the spritesheet.</param>
        /// <param name="nbFrames">The number of frames used in the animation.</param>
        /// <param name="frameWidth">Width of a frame in this animation.</param>
        /// <param name="frameWidth">Duration of a frame in this animation.</param>
        public Animation(Vector2 position, Rectangle? sourceRectangle, int nbFrames, int frameWidth, float frameDuration) : base (position, sourceRectangle)
        {
            this.nbFrames = nbFrames;
            this.frameWidth = frameWidth;
            this.frameDuration = frameDuration;
            this.index = 0;
            this.initialSpriteSheetPosition = new Vector2(sourceRectangle.Value.Location.X, sourceRectangle.Value.Location.Y);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Updates the animation in function of the specified game time.
        /// </summary>
        /// <param name="gameTime">A snapshot of the current time.</param>
        public void Update(GameTime gameTime)
        {
            this.index += gameTime.ElapsedGameTime.Milliseconds * this.frameDuration;
            this.SourceRectangle = new Rectangle((int)this.initialSpriteSheetPosition.X + (int)index * this.frameWidth, (int)this.initialSpriteSheetPosition.Y, this.SourceRectangle.Value.Width, this.SourceRectangle.Value.Height);
        }

        /// <summary>
        /// Determines whether this instance is finish.
        /// </summary>
        /// <returns>
        ///   <c>true</c> if this instance is finish; otherwise, <c>false</c>.
        /// </returns>
        public bool IsFinish()
        {
            return this.index > this.nbFrames;
        }

        #endregion        
    }
}
